from fastapi import APIRouter, Depends, HTTPException, status, Query
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List, Dict, Any, Optional

from server.schemas.user import (
    UserCreate, UserRead, UserUpdate, UserDetailRead, LoginRequest, Token,
    UserPageResponse, RoleRead, BatchOperation, PageResponse
)
from server.services.user_service import UserService
from server.db.session import get_db
from server.core.config.settings import settings
from server.core.security import get_current_user
from server.schemas.user import TokenPayload

router = APIRouter()

@router.post("/register", response_model=UserRead, status_code=status.HTTP_201_CREATED)
async def register_user(
    user_in: UserCreate,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends()
):
    """用户注册接口"
    return await service.create_user(user_in, db=db)

@router.post("/login", response_model=Token)
async def login(
    login_data: LoginRequest,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends()
):
    """用户登录接口"
    user = await service.authenticate(login_data.username, login_data.password, db=db)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码错误"
        )

    # 检查用户状态
    if user.status != 1:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="用户已被禁用"
        )

    # 获取用户角色
    roles = await service.user_repository.get_user_roles(user.id, db=db)
    role_names = [role.name for role in roles]

    # 创建令牌
    access_token = service.create_access_token(
        subject=user.id,
        additional_claims={"roles": role_names}
    )
    refresh_token = service.create_refresh_token(subject=user.id)

    return {
        "access_token": access_token,
        "refresh_token": refresh_token,
        "token_type": "bearer",
        "expires_in": settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
    }

@router.post("/refresh", response_model=Token)
async def refresh_token(
    refresh_token: str,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends()
):
    """刷新访问令牌接口"
    try:
        # 验证刷新令牌
        payload = jwt.decode(
            refresh_token,
            settings.SECRET_KEY,
            algorithms=[settings.ALGORITHM]
        )
        user_id: str = payload.get("sub")
        token_type: str = payload.get("type")

        if user_id is None or token_type != "refresh":
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="无效的刷新令牌"
            )

        # 检查用户是否存在
        user = await service.user_repository.get_user_by_id(int(user_id), db=db)
        if not user or user.status != 1:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="用户不存在或已被禁用"
            )

        # 创建新的访问令牌
        roles = await service.user_repository.get_user_roles(user.id, db=db)
        role_names = [role.name for role in roles]

        access_token = service.create_access_token(
            subject=user.id,
            additional_claims={"roles": role_names}
        )

        return {
            "access_token": access_token,
            "refresh_token": refresh_token,
            "token_type": "bearer",
            "expires_in": settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
        }

    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="刷新令牌已过期或无效"
        )

@router.get("/me", response_model=UserDetailRead)
async def read_current_user(
    current_user: TokenPayload = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends()
):
    """获取当前登录用户信息"
    user = await service.user_repository.get_user_by_id(current_user.user_id, db=db)
    return UserDetailRead.from_orm(user)

@router.get("/{user_id}", response_model=UserDetailRead)
async def read_user(
    user_id: int,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """通过ID获取用户详情"
    # 检查权限：只能查看自己或拥有管理员权限
    if current_user.user_id != user_id:
        has_permission = await service.check_permission(
            current_user.user_id, "user:read:all", db=db
        )
        if not has_permission:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="没有权限查看该用户信息"
            )

    user = await service.get_user(user_id, db=db)
    return user

@router.get("/", response_model=UserPageResponse)
async def read_users(
    username: Optional[str] = None,
    email: Optional[str] = None,
    status: Optional[int] = None,
    role_id: Optional[int] = None,
    page: int = Query(1, ge=1),
    page_size: int = Query(10, ge=1, le=100),
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """获取用户列表（分页）"
    # 检查权限
    has_permission = await service.check_permission(
        current_user.user_id, "user:read:all", db=db
    )
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="没有权限查看用户列表"
        )

    # TODO: 实现带过滤条件的分页查询
    users = await service.get_users(
        skip=(page - 1) * page_size,
        limit=page_size,
        db=db
    )
    total = len(users)  # 实际应该查询总数

    return {
        "total": total,
        "page": page,
        "page_size": page_size,
        "total_pages": (total + page_size - 1) // page_size,
        "data": users
    }

@router.put("/{user_id}", response_model=UserRead)
async def update_user(
    user_id: int,
    user_in: UserUpdate,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """更新用户信息"
    # 检查权限：只能更新自己或拥有管理员权限
    if current_user.user_id != user_id:
        has_permission = await service.check_permission(
            current_user.user_id, "user:update:all", db=db
        )
        if not has_permission:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="没有权限更新该用户信息"
            )

    return await service.update_user(user_id, user_in, db=db)

@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_user(
    user_id: int,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """删除用户"
    # 检查权限：需要管理员权限
    has_permission = await service.check_permission(
        current_user.user_id, "user:delete", db=db
    )
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="没有权限删除用户"
        )

    # 防止删除自己
    if current_user.user_id == user_id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能删除自己的账户"
        )

    success = await service.delete_user(user_id, db=db)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="用户不存在"
        )
    return {}

@router.post("/batch-delete", response_model=Dict[str, Any])
async def batch_delete_users(
    batch: BatchOperation,
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """批量删除用户"
    # 检查权限
    has_permission = await service.check_permission(
        current_user.user_id, "user:delete", db=db
    )
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="没有权限删除用户"
        )

    # 防止删除自己
    if current_user.user_id in batch.ids:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="不能删除自己的账户"
        )

    # 批量删除
    success_count = 0
    fail_count = 0
    for user_id in batch.ids:
        success = await service.delete_user(user_id, db=db)
        if success:
            success_count += 1
        else:
            fail_count += 1

    return {
        "success": True,
        "message": f"成功删除{success_count}个用户，失败{fail_count}个",
        "success_count": success_count,
        "fail_count": fail_count
    }

@router.post("/{user_id}/roles", response_model=UserDetailRead)
async def assign_roles_to_user(
    user_id: int,
    role_ids: List[int],
    db: AsyncSession = Depends(get_db),
    service: UserService = Depends(),
    current_user: TokenPayload = Depends(get_current_user)
):
    """分配角色给用户"
    # 检查权限
    has_permission = await service.check_permission(
        current_user.user_id, "user:assign:role", db=db
    )
    if not has_permission:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="没有权限分配角色"
        )

    # 更新用户角色
    user_in = UserUpdate(role_ids=role_ids)
    user = await service.update_user(user_id, user_in, db=db)
    return await service.get_user(user_id, db=db)